package model

import (
	"github.com/streadway/handy/atomic"
	"github.com/tianjigames/fairy/constants"
	protos2 "github.com/tianjigames/fairy/protos"
)

const (
	TempObjTick = 0
	TempMsgTick = 1
	TempOmsgTick = 2
	TempEventTick = 3
	TempCopyTTick = 4
	TempObjAtick = 5
	TempObjOTick = 6
	TempObjMotionTick = 7
	TempObjImpacTick = 8
	TempObjUpdaTezoneTick = 9
	TempObjAiBaseTick = 10
	TempObjAiControlTick = 11
	TempObjAiMoveTotick = 12
	TempObjAiJuagestateTick = 13
	TempCheckAreaTick = 14

)

type Scene struct {
	TempTTickNum    int
	curThreadId     string
	MEfficiencyData []*TickTimeData
	MnSceneId       int
	MSceneData      *SceneData
	MCopySceneData  *CopySceneData
	MObjManager *ObjManager
	MTriggerManager *MonsterTriggerManager
	MZoneList       []*Zone
	MRect           []*Rect
	MNPlayerNum     int
	MNSublineNum    int
	MSublineTimer   *NowTimer
	MScanInfo       *ScanInfo
	MZoneInfo       *ZoneInfo
	MNextNpcIndex   atomic.Int
	MNSceneStatus   SceneState
	LastTickTimer   int64
	MMoonMap        *MoonMap
	MAEventAreaList []*EventArea
	MATickCount     *SceneTickCount
	SceneNpcDataMap map[string]*SceneNpcData
	Boss            *NpcPlayer
}

func NewScene() *Scene {
	tempTTickNum := TempObjAiJuagestateTick + 2
	return &Scene{
		TempTTickNum: tempTTickNum,
		MEfficiencyData: make([]*TickTimeData,tempTTickNum),
		MATickCount: &SceneTickCount{},
	}
}

func (p *Scene) GetSceneTickCount() int {
	return p.MATickCount.GetTickCount()
}

/**
虎丘某个角色周围的角色
 */
func (p *Scene) GetAroundPlayerList(player IBaseObj,nRadius,nZoneID int,typ protos2.ObjType,bAndSelf bool) []IBaseObj {
	if player == nil {
		return nil
	}

	p.MScanInfo.Type = typ
	p.MScanInfo.MNZoneRadius = nRadius
	//获取格子矩形
	p.GetRectInRedius(nRadius,nZoneID,true)
	//扫描格子中所有的角色
	
	return p.ScanRect(player,p.MRect[0],nil,bAndSelf)
}

/**
扫描矩形中所有的角色
 */
func (p *Scene) ScanRect(obj IBaseObj,rcA,rcB *Rect,bAndSelf bool) []IBaseObj {
	rc := rcA
	if rc == nil {
		rc = p.MScanInfo.MRect
	}

	scanList := make([]IBaseObj,0)
	bNeedRet := false
	for h := rc.NStartz;h<= rc.NEndz;h ++ {
		if bNeedRet {
			break
		}

		for w := rc.NStartx;w <= rc.NEndx; w++ {
			if bNeedRet {
				break
			}

			if rcB != nil && rcB.IsContain(w,h) {
				continue
			}

			newID := w + h*p.MZoneInfo.MNZoneWSize
			pList := p.MZoneList[newID].MObjList
			for _,it := range pList {
				if charItem,ok1 := it.(CharObj);ok1 && charItem.GetZoneID() != newID {
					continue
				}

				if p.MScanInfo.Type != protos2.ObjType_ObtNone && p.MScanInfo.Type != it.GetType() {
					continue
				}

				if obj != nil && it.GetId() == obj.GetId() && it.GetType() == obj.GetType() && !bAndSelf {
					continue
				}

				scanList = append(scanList,it)
				if len(scanList) > constants.MaxObjScanListSize {
					bNeedRet = true
					break
				}
			}
		}
	}

	return scanList
}

/**
获取某个格子周围的格子
 */
func (p *Scene) GetRectInRedius(nRadius,nZoneId int,bIsOld bool)  {
	nRectIndex := 0
	if !bIsOld {
		nRectIndex = 1
	}

	p.MRect[nRectIndex].ClearUp()

	if nZoneId <= -1 {
		return
	}

	nW := nZoneId % p.MZoneInfo.MNZoneWSize
	nH := nZoneId / p.MZoneInfo.MNZoneWSize

	if nRadius < 0 {
		nRadius = 0
	}

	p.MRect[nRectIndex].NStartx = nW - nRadius
	p.MRect[nRectIndex].NStartz = nH - nRadius
	p.MRect[nRectIndex].NEndx = nW + nRadius
	p.MRect[nRectIndex].NEndz = nH + nRadius
	p.NormalRect(p.MRect[nRectIndex])
}

/**
修正矩形边界
 */
func (p *Scene) NormalRect(rc *Rect)  {
	if rc.NStartx < 0 {
		rc.NStartx = 0
	}

	if rc.NStartz < 0 {
		rc.NStartz = 0
	}

	if rc.NEndx >= p.MZoneInfo.MNZoneWSize {
		rc.NEndx = p.MZoneInfo.MNZoneWSize - 1
	}

	if rc.NEndz >= p.MZoneInfo.MNZoneHSize {
		rc.NEndz = p.MZoneInfo.MNZoneHSize - 1
	}
}
